package com.jinzhi.jzweb.service.resourceLibrary.impl;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.base.CoreServiceImpl;
import com.jinzhi.common.utils.Result;
import com.jinzhi.eventresource.main.EventresourceAllocationDO;
import com.jinzhi.eventresource.service.EventresourceAllocationService;
import com.jinzhi.jzweb.dao.resourceLibrary.SecretKeyDao;
import com.jinzhi.jzweb.domain.RegionDO;
import com.jinzhi.jzweb.domain.resourceLibrary.SecretAssets;
import com.jinzhi.jzweb.domain.resourceLibrary.SecretKey;
import com.jinzhi.jzweb.pojo.RegionItemVO;
import com.jinzhi.jzweb.service.RegionService;
import com.jinzhi.jzweb.service.resourceLibrary.SecretAssetsService;
import com.jinzhi.jzweb.service.resourceLibrary.SecretKeyService;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * (SecretKey)表服务实现类
 *
 * @author makejava
 * @since 2024-05-09 10:24:38
 */
@Service("secretKeyService")
public class SecretKeyServiceImpl extends CoreServiceImpl<SecretKeyDao, SecretKey> implements SecretKeyService {


    private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    /**
     * 资源秘钥关联业务
     */
    private final SecretAssetsService secretAssetsService;

    /**
     * 用户
     *
     * @param secretAssetsService
     */
    private final UserService userService;

    /**
     * 资源信息
     */
    private final EventresourceAllocationService eventresourceAllocationService;

    @Autowired
    private RegionService regionService;


    public SecretKeyServiceImpl(SecretAssetsService secretAssetsService, UserService userService, EventresourceAllocationService eventresourceAllocationService) {
        this.secretAssetsService = secretAssetsService;
        this.userService = userService;
        this.eventresourceAllocationService = eventresourceAllocationService;
    }

    @Override
    public Result saveSecretKey(SecretKey secretKey) {
//        if (secretKey.getType() == 0) {
            LocalDateTime maxDateTime = LocalDateTime.of(9999, 12, 31, 23, 59, 59);
            secretKey.setExpirationDate(maxDateTime);
//        }
        secretKey.setSecretKey(generateKey(20));
        Boolean aBoolean = this.insert(secretKey);
        if (secretKey.getSecretAssets() == null || secretKey.getSecretAssets().isEmpty()) {
            return Result.ok(aBoolean);
        }
        //资源信息不为null
        secretKey.getSecretAssets().forEach(a -> {
            a.setSecretId(secretKey.getId());
        });
        return Result.ok(secretAssetsService.insertBatch(secretKey.getSecretAssets()));
    }

    public static String generateKey(int length) {
        StringBuilder sb = new StringBuilder(length);
        SecureRandom secureRandom = new SecureRandom();
        for (int i = 0; i < length; i++) {
            int index = secureRandom.nextInt(ALPHA_NUMERIC_STRING.length());
            sb.append(ALPHA_NUMERIC_STRING.charAt(index));
        }
        return sb.toString();
    }

    @Override
    @Transactional
    public Result editSecretKey(SecretKey secretKey) {
//        if (secretKey.getType() == 0) {
            LocalDateTime maxDateTime = LocalDateTime.of(9999, 12, 31, 23, 59, 59);
            secretKey.setExpirationDate(maxDateTime);
//        }
        //修改秘钥信息
        Boolean aBoolean = this.updateById(secretKey);
        if (secretKey.getSecretAssets() == null || secretKey.getSecretAssets().isEmpty()) {
            return Result.ok(aBoolean);
        }
        //删除资源信息
        secretAssetsService.delete(new EntityWrapper<SecretAssets>().eq("secret_id", secretKey.getId()));
        //新增资源信息
        //资源信息不为null
        secretKey.getSecretAssets().forEach(a -> {
            a.setSecretId(secretKey.getId());
        });
        return Result.ok(secretAssetsService.insertBatch(secretKey.getSecretAssets()));
    }

    @Override
    public Result getSecretKyPage(SecretKey secretKey) {
        List<UserDO> userDOList;
        if (ObjectUtil.isNotEmpty(secretKey.getUserName())) {
            EntityWrapper<UserDO> wrapper = new EntityWrapper<>();
            wrapper.like("username", secretKey.getUserName());
            wrapper.eq("user_from", 1);
            userDOList = userService.selectList(wrapper);
        } else {
            userDOList = null;
        }

        Page<SecretKey> page = new Page<SecretKey>(secretKey.getCurrent(), secretKey.getSize());
        Page<SecretKey> secretKeyPage = this.selectPage(page, new EntityWrapper<SecretKey>()
                .eq(Objects.nonNull(secretKey.getStatus()), "status", secretKey.getStatus())
                .like(ObjectUtil.isNotEmpty(secretKey.getUnitName()), "unit_name", secretKey.getUnitName()));
//                .like(Objects.nonNull(secretKey.getSecretKey()), "secret_key", secretKey.getSecretKey()));
        if (secretKeyPage.getRecords().isEmpty()) {
            return Result.ok(secretKeyPage);
        }
        //拿到使用人id集合
        List<Long> ids = secretKeyPage.getRecords().stream().map(SecretKey::getUserId).collect(Collectors.toList());
        List<UserDO> userDOS = userService.selectList(new EntityWrapper<UserDO>().in("id", ids));
        if (userDOS.isEmpty()) {
            return Result.ok(secretKeyPage);
        }
        secretKeyPage.getRecords().forEach(a -> userDOS.forEach(b -> {
            if (Objects.equals(a.getUserId(), b.getId())) {
                a.setUserName(b.getUsername());
            }
        }));

        // 使用人查询
        if (ObjectUtil.isNotNull(userDOList)) {

            List<SecretKey> collect = secretKeyPage.getRecords().stream()
                    .filter(record -> {
                        for (UserDO userDO : userDOList) {
                            if (ObjectUtil.equal(userDO.getId(), record.getUserId())) {
                                return true;
                            }
                        }
                        return false;
                    }).collect(Collectors.toList());

            secretKeyPage.setRecords(collect);
        }
        return Result.ok(secretKeyPage);
    }

    @Override
    public SecretKey getSecretKy(Long id) {
        //根据秘钥id获取秘钥信息
        SecretKey secretKey = this.selectById(id);
        //获取使用人名称
        secretKey.setUserName(Optional.ofNullable(userService.selectById(secretKey.getUserId())).orElse(new UserDO()).getName());
        //获取所有资源信息
        List<EventresourceAllocationDO> evens = eventresourceAllocationService.evens();
        if (evens.isEmpty()) {
            return secretKey;
        }
        //获取秘钥关联资源信息
        List<SecretAssets> secretAssets = secretAssetsService.selectList(new EntityWrapper<SecretAssets>().eq("secret_id", id));
        //没有相关资源不做后续算法
        if (secretAssets.isEmpty()) {
            Map<String, List<EventresourceAllocationDO>> map = evens.stream().collect(Collectors.groupingBy(EventresourceAllocationDO::getEveMoName));
            secretKey.setEventrMap(map);
            return secretKey;
        }
        //对比是否已有资源，以后资源该状态为已选择
        evens.forEach(a -> secretAssets.forEach(b -> {
            if (Objects.equals(a.getId(), b.getAllocationId())) {
                a.setIsShow(1);
            }
        }));
        Map<String, List<EventresourceAllocationDO>> map = evens.stream().collect(Collectors.groupingBy(EventresourceAllocationDO::getEveMoName));
        secretKey.setEventrMap(map);
        return secretKey;
    }


    @Override
    public Map<String, List<EventresourceAllocationDO>> getAddSecretKy() {
        Map<String, List<EventresourceAllocationDO>> map = new HashMap<>();
        //获取所有资源信息
        List<EventresourceAllocationDO> evens = eventresourceAllocationService.evens();
        if (evens.isEmpty()) {
            return map;
        }
        map = evens.stream().collect(Collectors.groupingBy(EventresourceAllocationDO::getEveMoName));
        return map;
    }


    @Override
    public void timingEffect() {
        //查询所有时效秘钥
        List<SecretKey> secretKeys = this.selectList(new EntityWrapper<SecretKey>().eq("type", 1));
        if (secretKeys.isEmpty()) {
            return;
        }
        //获取所有时间已过期的秘钥并改变状态为已过期
        secretKeys = secretKeys.stream().filter(a -> !LocalDateTime.now().isBefore(a.getExpirationDate())).peek(b -> b.setStatus(2)).collect(Collectors.toList());
        //验证是否有已过期的秘钥
        if (secretKeys.isEmpty()) {
            return;
        }
        this.updateBatchById(secretKeys);
    }

    @Override
    public Result removeById(Long id) {
        this.deleteById(id);
        return Result.ok(secretAssetsService.delete(new EntityWrapper<SecretAssets>().eq("secret_id", id)));
    }

    @Override
    public Result permissionVerification(Long userId, Long allocationId) {
        Boolean ab = false;
        //获取用户类型
        Integer type = userService.selectById(userId).getType();
        if (Objects.isNull(type)) {
            return Result.ok(ab);
        }

        //1==教师
        if (type == 1) {
            ab = Optional.of(this.baseMapper.isAssets(userId, allocationId)).isPresent();
            return Result.ok(ab);
        }

        //0==学生,获取教师id
        Long id = this.baseMapper.getTeacherById(userId);
        if (Objects.isNull(id)) {
            return Result.ok(ab);
        }
        if (type == 0) {
            ab = Optional.of(this.baseMapper.isAssets(id, allocationId)).isPresent();
            return Result.ok(ab);
        }
        return Result.ok(ab);
    }

    @Override
    public List<RegionItemVO> getRegionTree() {
        List<RegionItemVO> areaItemVoList = new ArrayList<>();

        //查询出所有省市区数据
        List<RegionDO> provinceCityRegionEntityList = regionService.selectList(null);
        //过滤出所有省
        List<RegionDO> fatherList = provinceCityRegionEntityList.stream().filter(item -> {
            if (item.getParentId().equals("0")) {
                return true;
            } else {
                return false;
            }
        }).collect(Collectors.toList());

        for (RegionDO father : fatherList) {
            RegionItemVO areaItemVo = new RegionItemVO();
            areaItemVo.setId(father.getId());
            areaItemVo.setValue(father.getName());
            this.searchSon(areaItemVo, provinceCityRegionEntityList);
            areaItemVoList.add(areaItemVo);
        }

        return areaItemVoList;
    }

    private void searchSon(RegionItemVO father, List<RegionDO> provinceCityRegionEntityList) {
        List<RegionItemVO> sonList = provinceCityRegionEntityList.stream().filter(item -> {
            if (item.getParentId().equals(String.valueOf(father.getId()))) {
                return true;
            } else {
                return false;
            }
        }).map(item1 -> {
            RegionItemVO son = new RegionItemVO();
            son.setId(item1.getId());
            son.setValue(item1.getName());
            //继续给儿子寻找孙子
            this.searchSon(son, provinceCityRegionEntityList);
            return son;
        }).collect(Collectors.toList());
        father.setChildrenList(sonList);
    }
}

